package alp.starcode.nudtportal.framework.config.rabbitmq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

/**
 * 消费工厂配置类
 *
 * @Author wj
 * @Date 2023/8/2 9:16
 */

@Slf4j
@Configuration
public class RabbitMqConfig {

    @Autowired
    private RabbitProperties properties;

    @Bean("getRabbitAdmin")
    public RabbitAdmin getRabbitAdmin(
            @Qualifier("getCachingConnectionFactory") CachingConnectionFactory connectionFactory
    ) {
        return new RabbitAdmin(connectionFactory);
    }

    @Bean("getCachingConnectionFactory")
    public CachingConnectionFactory getCachingConnectionFactory() {
        CachingConnectionFactory connectionFactory = buildFactory();
        connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CONNECTION);
        connectionFactory.getRabbitConnectionFactory().setRequestedChannelMax(4095);
        //设置缓存中保存20个信道，根据业务量来配置信道大小
        connectionFactory.setConnectionCacheSize(20);
        connectionFactory.setChannelCheckoutTimeout(10000);
        return connectionFactory;
    }

    /**
     * 配置通用属性
     *
     * @return
     */
    private CachingConnectionFactory buildFactory() {
        PropertyMapper map = PropertyMapper.get();
        CachingConnectionFactory factory = new CachingConnectionFactory();
        map.from(properties::determineAddresses).to(factory::setAddresses);
        map.from(properties::determineUsername).whenNonNull().to(factory::setUsername);
        map.from(properties::determinePassword).whenNonNull().to(factory::setPassword);
        map.from(properties::determineVirtualHost).whenNonNull().to(factory::setVirtualHost);
        return factory;
    }
}
